package com.ssd.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.google.common.collect.Lists;
import com.ssd.view.AbstractEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.Collection;
import java.util.List;
import java.util.function.Function;

/**
 * 用于处理Excel文件的数据读取和批量保存
 * @param <T>
 * @param <E>
 */
@Slf4j
public class ExcelDataListener<T extends AbstractEntity, E> extends AnalysisEventListener<E> {
    //存储转换后的实体对象列表
    private List<T>  list= Lists.newArrayList();
    //目标实体类的类对象
    private Class<T> clazz;
    //批量保存数据的函数
    private Function<Collection<T>,Boolean> saveFunc;
    //批量保存的阈值，设置为500
    private static final int BATCH_COUNT=500;

    /**
     * 提取数据
     * @param e
     * @param analysisContext
     */
    @Override
    public void invoke(E e, AnalysisContext analysisContext) {

        //每次读取一行数据时调用，将Excel数据转换为目标实体并添加到列表中
        // ，当列表达到 BATCH_COUNT 时调用 doAfterAllAnalysed 方法。
        try {
            T t= clazz.getDeclaredConstructor(null).newInstance();
            BeanUtils.copyProperties( e,t );
            list.add(t);
            if( list.size()>=BATCH_COUNT ){
                doAfterAllAnalysed(null);
            }

        } catch (Exception ex) {
           log.error("读取excel出错");
        }


    }


    /**
     * 读取完成
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //在所有数据读取完成后调用，批量保存数据并清空列表。
        saveFunc.apply(list);
        list.clear();
    }


    public ExcelDataListener(Function<Collection<T>,Boolean> saveFunc,Class<T> clazz){
        this.saveFunc=saveFunc;
        this.clazz=clazz;
    }

}
